#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>

#include <sys/stat.h>
#include <fcntl.h>
#include <map>


#define PORT 9090
#define Size 1024


struct FileName
{
    FileName(){};
    FileName(const char * name,size_t flag)
    {
        memcpy(m_name, name,strlen(name));
        m_flag = flag;
    }
    char m_name[Size];
    size_t m_flag;
};

int main()
{
    /* 创建socket句柄 */
    int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd == -1)
    {
        perror("sock error");
        exit(1);
    }


    /* 绑定IP + 端口号 */
/* 设置地址 */
    int optVal = 1;
    /* 端口复用 多个进程监听同一个端口*/
    int ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(optVal));
    if (ret == -1)
    {
        perror("setsockopt error");
        exit(1);
    }
    // 绑定服务器的IP和端口
    sockaddr_in localAddress;
    // 清除脏数据
    memset(&localAddress, 0, sizeof(localAddress));
    // 地址族
    localAddress.sin_family = AF_INET;         // ipv4
    localAddress.sin_port = htons(PORT);       // 端口
    localAddress.sin_addr.s_addr = INADDR_ANY; // 设置IP地址 INADDR_ANY:通常为0.0.0.0，代表绑定到所有可用的网络接口 addr(地址)

    // 绑定
    ret = bind(sockfd, (const sockaddr *)&localAddress, sizeof(localAddress));
    if (ret == -1)
    {
        perror("bind error:");
        _exit(-1);
    }
    char buffer[Size] = {0};
    FileName files;

    ssize_t size = recvfrom(sockfd,&files,sizeof(FileName),0,NULL,NULL);

    int writefd = open(files.m_name,O_CREAT | O_WRONLY,0777);

    while(1)
    {
        memset(&files,0,sizeof(FileName));
        ssize_t size = recvfrom(sockfd,&files,sizeof(FileName),0,NULL,NULL);
        if(size < 0)
        {
            perror("recform error");
            exit(-1);
        }
        else if(size == 0)
        {
            std::cout << " size = 0 " << std::endl;
            break;
        }
        else
        {
            lseek(writefd,files.m_flag,SEEK_SET);
            write(writefd,files.m_name,strlen(files.m_name));
        }
        /* 清空脏数据 */
        

    }






    pause();

    return 0;
}